package cn.yunbamboos.rest.service.logs;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

public class LogMetadata implements ILogMetadata {

    /**
     * 接触ID
     */
    private String traceId;

    private String loginTraceId;
    /**
     * 操作用户ID
     */
    private long userId;
    /**
     * 客户端IP
     */
    private String clientIp;
    /**
     * 客户端
     */
    private String browser;
    /**
     * 服务名称
     */
    private String serviceName;
    /**
     * 服务路径
     */
    private String servicePath;
    /**
     * 实际URL
     */
    private String realUrl;
    /**
     * 服务开始时间
     */
    private LocalDateTime startTime;
    /**
     * 服务耗时
     */
    private long time;
    /**
     * 服务返回编码
     */
    private int code;
    /**
     * 服务返回内容
     */
    private String msg;
    /**
     * 服务入参
     */
    private String in;
    /**
     * 服务返回
     */
    private String out;

    private Map<String, Object> attributes;

    @Override
    public String toString() {
        String template = """
                {\s
                  traceId: {}\s
                  userId: {}\s
                  client_ip: {}\s
                  browser: {}\s
                  serviceName: {}\s
                  servicePath: {}\s
                  realUrl: {}\s
                  startTime: {}\s
                  time: {}\s
                  code: {}\s
                  msg: {}\s
                  attributes: {}\s
                }""";
        String  startTime = LocalDateTimeUtil.format(this.startTime, DatePattern.NORM_DATETIME_MS_PATTERN);
        return StrUtil.format(template, traceId, userId, clientIp, browser, serviceName, servicePath, realUrl, startTime, time, code, msg, JSON.toJSONString(attributes));
    }

    protected void setTraceId(String traceId) {
        this.traceId = traceId;
    }

    protected void setUserId(long userId) {
        this.userId = userId;
    }

    protected void setLoginTraceId(String loginTraceId){
        this.loginTraceId = loginTraceId;
    }

    protected void setClientIp(String clientIp) {
        this.clientIp = clientIp;
    }

    protected void setBrowser(String browser) {
        this.browser = browser;
    }

    protected void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }

    protected void setServicePath(String servicePath) {
        this.servicePath = servicePath;
    }

    protected void setRealUrl(String realUrl) {
        this.realUrl = realUrl;
    }

    protected void setStartTime(LocalDateTime startTime) {
        this.startTime = startTime;
    }

    protected void setTime(long time) {
        this.time = time;
    }

    protected void setCode(int code) {
        this.code = code;
    }

    protected void setMsg(String msg) {
        this.msg = msg;
    }

    protected void setIn(String in) {
        this.in = in;
    }

    protected void setOut(String out) {
        this.out = out;
    }

    public void setAttribute(String key, Object value) {
        if(ObjUtil.isNull(this.attributes)){
            this.attributes = new HashMap<>();
        }
        this.attributes.put(key, value);
    }

    public String getTraceId() {
        return traceId;
    }

    public String getLoginTraceId() {
        return loginTraceId;
    }

    public long getUserId() {
        return userId;
    }

    public String getClientIp() {
        return clientIp;
    }

    public String getBrowser() {
        return browser;
    }

    public String getServiceName() {
        return serviceName;
    }

    public String getServicePath() {
        return servicePath;
    }

    public String getRealUrl() {
        return realUrl;
    }

    public LocalDateTime getStartTime() {
        return startTime;
    }

    public long getTime() {
        return time;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public String getIn() {
        return in;
    }

    public String getOut() {
        return out;
    }

    public boolean getAttributeForBoolean(String key) {
        if(this.attributes == null){
            return false;
        }
        if(!this.attributes.containsKey(key)){
            return false;
        }
        Object value = this.attributes.get(key);
        if(value instanceof Boolean val){
            return val;
        } else if(value instanceof String val){
            return !StrUtil.isBlank(val) && Boolean.parseBoolean(val);
        } else {
            return false;
        }
    }

    public <T> T getAttributeForObject(String key, Class<T> clazz){
        if(this.attributes == null){
            return null;
        }
        if(!this.attributes.containsKey(key)){
            return null;
        }
        Object value = this.attributes.get(key);
        return Convert.convert(clazz, value);
    }

    public Map<String, Object> getAttributes() {
        return attributes;
    }




}
